package com.onpositive.data.serializer.readers;

import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.BitSet;
import java.util.LinkedHashSet;

import com.onpositive.data.FilterTester;
import com.onpositive.data.serializer.writers.AbstractWriter;
import com.onpositive.data.serializer.writers.IntWriter;

public class IntReader extends CollectionReader<Integer> {

	// private static final int INT_SIZE = 4 ;
	private static final int defaultValue = Integer.MIN_VALUE;
	private int[] primitiveValuesArrays;

	public IntReader() {
		super(Integer.class);
	}

	@Override
	protected void initValuesAray(byte[] byteData) {

		primitiveValuesArrays = new int[size];

		ByteBuffer bBuf = ByteBuffer.wrap(byteData);

		boolean continueIteration = true;
		int start = 0;
		int end = emptyCells.nextSetBit(0);
		for (; continueIteration;) {
			for (int i = start; i < end; i++)
				primitiveValuesArrays[i] = bBuf.getInt();

			if (end < size)
				primitiveValuesArrays[end] = defaultValue;

			start = end + 1;
			end = emptyCells.nextSetBit(start);
			end = end >= 0 ? end : size;
			continueIteration = start <= size;
		}
	}

	@Override
	protected Integer doGet(int i) {
		int j = primitiveValuesArrays[i];
		if (j==defaultValue){
			return null;
		}
		return j;
	}

	@Override
	protected Integer defaultObject() {
		return defaultValue;
	}

	@Override
	protected Integer readObject(ByteBuffer bBuf) {

		return bBuf.getInt();
	}

	@Override
	public void filterOut(LinkedHashSet<Object> obj, String text) {

	}

	@Override
	public boolean accept(int op, int a, Object constraint) {
		if( !isInitialized() )
			init() ;
		boolean b = emptyCells.get(a);
		if (constraint == null) {
			switch (op) {
			case FilterTester.GE:
			case FilterTester.LE:
			case FilterTester.EQ:
				return b;

			case FilterTester.NEQ:
				return !b;

			default:
				break;
			}
			return false;
		}
		if (b) {			
			return false;
		}
		int i = primitiveValuesArrays[a];

		Number m = (Number) constraint;
		int ww = m.intValue();
		switch (op) {
		case FilterTester.EQ:
			return ww == i;
		case FilterTester.NEQ:
			return ww != i;
		case FilterTester.LE:
			return ww >= i;
		case FilterTester.LT:
			return ww > i;
		case FilterTester.GT:
			return ww < i;
		case FilterTester.GE:
			return ww <= i;
		case FilterTester.CONTAINS:
			return ww == i;
		default:
			throw new UnsupportedOperationException();
		}
	}

	@Override
	public Object aggregate(int op, BitSet ss) {
		
		return null;
	}

	@Override
	public void setValue(int num, Object value) {
		
	}

	@Override
	public AbstractWriter<Integer> getWriter() {
		return new IntWriter();
	}

	@Override
	public void initEmpty(int dataSize) {
		primitiveValuesArrays=new int[dataSize];
		setInitialized();
	}
	@Override
	public void expand(int newSize) {
		if (!isInitialized()){
			init();
		}
		int[] m=new int[newSize];
		System.arraycopy(primitiveValuesArrays, 0, m, 0, primitiveValuesArrays.length);
		for (int a=primitiveValuesArrays.length;a<m.length;a++){
			m[a]=defaultValue;
		}
		primitiveValuesArrays=m;
	}
}
